<?php


namespace App\Services;


use App\Models\BidGoods;
use App\Models\BidGoodsMain;
use App\Models\Bid;
use App\Models\Goods;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Tymon\JWTAuth\Contracts\JWTSubject;
use App\Utils\Code;

class BidGoodsService extends BaseService
{

    /**
     * 创建
     * @param array $params
     * @return Builder|\Illuminate\Database\Eloquent\Model|object|JWTSubject|null
     * @throws \Exception
     */
    public function store(array $params) {
        if (\DB::table('user_extra')->where('user_id', \Auth::id())->value('can_bid') == 0) {
            throw new \Exception('您目前没有投标权限，请先联系管理员获取投标权限', Code::PARAMETER_ERROR);
        }
        if (!$bid = Bid::where('status', 1)->whereNull('deleted_at')->first()) {
            throw new \Exception('暂无进行中的投标', Code::PARAMETER_ERROR);
        }
        if (isset($params['goods_id']) && $params['goods_id']) {
            $goods = Goods::where('goods_id', (int)$params['goods_id'])->whereNull('deleted_at')->first();
        } elseif (isset($params['goods_code']) && $params['goods_code']) {
            $goods = Goods::where('goods_code', $params['goods_code'])->whereNull('deleted_at')->first();
        } else {
            throw new \Exception('商品主键或商品编号不能为空', Code::PARAMETER_ERROR);
        }
        if (!$goods) {
            throw new \Exception('商品不存在，请检查商品编号是否有误', Code::PARAMETER_ERROR);
        }
        if (!isset($params['price']) || !$params['price'] || !is_numeric($params['price'])) {
            throw new \Exception('投标价格不能为空', Code::PARAMETER_ERROR);
        }
        if (!$goods->is_bid) {
            throw new \Exception('该商品不参与投标', Code::PARAMETER_ERROR);
        }
        if (!$goods->is_onshelf) {
            throw new \Exception('该商品已下架', Code::PARAMETER_ERROR);
        }
        if ($params['price'] < $goods->label_price) {
            throw new \Exception('投标价格不能低于底价', Code::PARAMETER_ERROR);
        }
        $userId = \Auth::id();
        return \DB::transaction(function () use ($params, $bid, $goods, $userId) {
            $model = new BidGoods();
            $model->user_id = $userId;
            $model->goods_id = $goods->goods_id;
            $model->bid_id = $bid->bid_id;
            $model->price = (double)$params['price'];
            $bidGoods = BidGoods::where('goods_id', $goods->goods_id)
                ->where('user_id', $userId)
                ->where('bid_id', $bid->bid_id)
                ->where('is_max', 1)
                ->first();
            if ($bidGoods && $bidGoods->price >= $model->price) {
                $model->is_max = 0;
            } elseif ($bidGoods && $bidGoods->price < $model->price) {
                $model->is_max = 1;
                $bidGoods->is_max = 0;
                $bidGoods->save();
            } else {
                $model->is_max = 1;
            }
            $model->save();
            if (!$main = BidGoodsMain::where('bid_id', $model->bid_id)
                ->where('goods_id', $model->goods_id)
                ->lockForUpdate()
                ->first()) {
                $main = new BidGoodsMain();
                $main->bid_id = $model->bid_id;
                $main->goods_id = $model->goods_id;
                $main->max_price = $model->price;
                $main->max_user_id = $model->user_id;
                $main->min_price = $model->price;
                $main->min_user_id = $model->user_id;
                $main->save();
            }
            if ($model->price > $main->max_price) {
                $main->max_price = $model->price;
                $main->max_user_id = $model->user_id;
            }
            if ($model->price < $main->min_price) {
                $main->min_price = $model->price;
                $main->min_user_id = $model->user_id;
            }
            $main->save();
            return $model;
        });
    }

    /**
     * 查看列表
     * @param array $params
     * @return Builder|\Illuminate\Database\Eloquent\Model|object|JWTSubject|null
     * @throws \Exception
     */
    public function index(array $params) {
        $model = BidGoods::with([
            'goods' => function(BelongsTo $belongsTo) {
                $belongsTo->with([
                    'cover', 'supplier'
                ]);
            },
            'bid'
        ]);
        if (isset($params['is_max'])) {
            $model = $model->where('is_max', (int)$params['is_max']);
        }
        // 默认用户
        if ($this::$admin && isset($params['user_id']) && $params['user_id']) {
            $model = $model->where('user_id', (int)$params['user_id']);
        } else {
            $model = $model->where('user_id', \Auth::id());
        }
        // 默认场次
        // $bid = Bid::where('status', 1)->whereNull('deleted_at')->first();
        // if ($this::$admin && isset($params['bid_id']) && $params['bid_id']) {
        //     $model = $model->where('bid_id', (int)$params['bid_id']);
        // } elseif (!$bid) {
        //     throw new \Exception('暂无进行中的投标', Code::PARAMETER_ERROR);
        // }
        // $model = $model->where('bid_id', $bid->bid_id);

        if (isset($params['goods_id']) && $params['goods_id']) {
            $model = $model->where('goods_id', $params['goods_id']);
        }
        return $model->orderBy('id', 'desc')
            ->paginate(isset($params['per_page']) ? (int)$params['per_page'] : null);
    }

    /**
     * 查看列表
     * @param array $params
     * @return Builder|\Illuminate\Database\Eloquent\Model|object|JWTSubject|null
     * @throws \Exception
     */
    // public function summary(array $params) {
    //     $model = BidGoods::with([
    //         'goods' => function(BelongsTo $belongsTo) {
    //             $belongsTo->with([
    //                 'cover', 'supplier'
    //             ]);
    //         },
    //         'bid'
    //     ]);
    //     if (!$this::$admin) {
    //         throw new \Exception('没有权限查看该信息', Code::UNAUTHORIZED_ACCESS);
    //     }
    //     if (isset($params['bid_code']) && $params['bid_code']) {
    //         $bid = Bid::where('bid_code', $params['bid_code'])->whereNull('deleted_at')->first();
    //         if (!$bid) {
    //             throw new \Exception('场次不存在，请检查场次代码', Code::PARAMETER_ERROR);
    //         }
    //     } elseif (isset($params['bid_id']) && $params['bid_id']) {
    //         $bid = Bid::where('bid_id', $params['bid_id'])->whereNull('deleted_at')->first();
    //         if (!$bid) {
    //             throw new \Exception('场次不存在', Code::PARAMETER_ERROR);
    //         }
    //     } else {
    //         $bid = Bid::where('status', 1)->whereNull('deleted_at')->first();
    //     }
    //     if ($bid) {
    //         $model = $model->where('bid_id', $bid->bid_id);
    //     }
    //     if (isset($params['ids']) && is_array($params['ids'])) {
    //         $model = $model->whereIn('id', $params['ids']);
    //     }
    //     // 商品信息筛选
    //     $model = $model->leftJoin('goods', 'goods.goods_id', '=', 'bid_goods.goods_id');
    //     if (isset($params['goods_code']) && $params['goods_code']) {
    //         $model->where('goods.goods_code', $params['goods_code']);
    //     }
    //     if (isset($params['supplier_id']) && $params['supplier_id']) {
    //         $model->where('goods.supplier_id', $params['supplier_id']);
    //     }
    //     if (isset($params['goods_name']) && $params['goods_name']) {
    //         $model->where('goods.goods_name', 'like', $params['goods_name'].'%');
    //     }
    //     if (isset($params['description']) && $params['description']) {
    //         $model->where('goods.description', 'like', $params['description'].'%');
    //     }
    //     if (isset($params['remarks']) && $params['remarks']) {
    //         $model->where('goods.remarks', 'like', $params['remarks'].'%');
    //     }
    //     $implode = [
    //         'bid_goods.bid_id',
    //         'bid_goods.goods_id',
    //         // 被投标次数
    //         'count(bid_goods.id) as bid_goods_count',
    //         // 参与投标人数
    //         'count(distinct(bid_goods.user_id)) as bid_user_count',
    //         // 最高出价
    //         "max(bid_goods.price) as max_price",
    //         // 最低出价
    //         "min(bid_goods.price) as min_price"
    //     ];
    //     $model = $model->groupBy('bid_goods.bid_id', 'bid_goods.goods_id')->select(\DB::raw(implode(',', $implode)));
    //     return $model->paginate(isset($params['per_page']) ? $params['per_page'] : 15);
    // }
    public function summary(array $params) {
        $model = BidGoodsMain::with([
            'goods' => function(BelongsTo $belongsTo) {
                $belongsTo->with([
                    'cover', 'supplier'
                ]);
            },
            'bid',
            'maxUser'
        ]);
        if (!$this::$admin) {
            throw new \Exception('没有权限查看该信息', Code::UNAUTHORIZED_ACCESS);
        }
        if (isset($params['bid_code']) && $params['bid_code']) {
            $bid = Bid::where('bid_code', $params['bid_code'])->whereNull('deleted_at')->first();
            if (!$bid) {
                throw new \Exception('场次不存在，请检查场次代码', Code::PARAMETER_ERROR);
            }
        } elseif (isset($params['bid_id']) && $params['bid_id']) {
            $bid = Bid::where('bid_id', $params['bid_id'])->whereNull('deleted_at')->first();
            if (!$bid) {
                throw new \Exception('场次不存在', Code::PARAMETER_ERROR);
            }
        } else {
            $bid = Bid::where('status', 1)->whereNull('deleted_at')->first();
        }
        if ($bid) {
            $model = $model->where('bid_id', $bid->bid_id);
        }
        if (isset($params['ids']) && is_array($params['ids'])) {
            $model = $model->whereIn('id', $params['ids']);
        }
        // 商品信息筛选
        $model = $model->leftJoin('goods', 'goods.goods_id', '=', 'bid_goods_main.goods_id');
        if (isset($params['goods_code']) && $params['goods_code']) {
            $model->where('goods.goods_code', $params['goods_code']);
        }
        if (isset($params['supplier_id']) && $params['supplier_id']) {
            $model->where('goods.supplier_id', $params['supplier_id']);
        }
        if (isset($params['goods_name']) && $params['goods_name']) {
            $model->where('goods.goods_name', 'like', $params['goods_name'].'%');
        }
        if (isset($params['remarks']) && $params['remarks']) {
            $model->where('goods.remarks', 'like', $params['remarks'].'%');
        }
        return $model->paginate(isset($params['per_page']) ? $params['per_page'] : 15);
    }

    /**
     * 查看列表
     * @param array $params
     * @return Builder|\Illuminate\Database\Eloquent\Model|object|JWTSubject|null
     * @throws \Exception
     */
    public function summaryUser(array $params) {
        $model = BidGoods::with([
            'goods' => function(BelongsTo $belongsTo) {
                $belongsTo->with([
                    'cover', 'supplier'
                ]);
            },
            'bid',
            'user'
        ]);
        if (!$this::$admin) {
            throw new \Exception('没有权限查看该信息', Code::UNAUTHORIZED_ACCESS);
        }
        if (isset($params['bid_code']) && $params['bid_code']) {
            $bid = Bid::where('bid_code', $params['bid_code'])->whereNull('deleted_at')->first();
            if (!$bid) {
                throw new \Exception('场次不存在，请检查场次代码', Code::PARAMETER_ERROR);
            }
        } elseif (isset($params['bid_id']) && $params['bid_id']) {
            $bid = Bid::where('bid_id', $params['bid_id'])->whereNull('deleted_at')->first();
            if (!$bid) {
                throw new \Exception('场次不存在', Code::PARAMETER_ERROR);
            }
        } else {
            $bid = Bid::where('status', 1)->whereNull('deleted_at')->first();
        }
        if ($bid) {
            $model = $model->where('bid_id', $bid->bid_id);
        } else {
            throw new \Exception('没有进行中的场次，请选择场次进行查询', Code::PARAMETER_ERROR);
        }
        if (isset($params['goods_code']) && $params['goods_code']) {
            $goods = Goods::where('goods_code', $params['goods_code'])->whereNull('deleted_at')->first();
            if (!$goods) {
                throw new \Exception('标品不存在，请检查标号', Code::PARAMETER_ERROR);
            }
            $model = $model->where('goods_id', $goods->goods_id);
        }
        // 用户信息筛选
        $model = $model->leftJoin('users', 'users.user_id', '=', 'bid_goods.user_id');
        if (isset($params['user_name']) && $params['user_name']) {
            $model->where('users.name', 'like', $params['user_name'].'%');
        }
        if (isset($params['user_phone']) && $params['user_phone']) {
            $model->where('users.phone', $params['user_phone']);
        }
        $implode = [
            'bid_goods.bid_id',
            'bid_goods.goods_id',
            'bid_goods.user_id',
            // 首次投标时间
            'min(bid_goods.created_at) as first_at',
            // 最新投标时间
            'max(bid_goods.created_at) as new_at',
            // 投标次数
            'count(bid_goods.id) as bid_goods_count',
            // 投标最高价
            "max(bid_goods.price) as max_price",
            // 投标最底价
            "min(bid_goods.price) as min_price"
        ];
        $model = $model->groupBy('bid_id', 'goods_id', 'user_id')->select(\DB::raw(implode(',', $implode)));
        if (isset($params['first_at']) && $params['first_at'] && is_array($params['first_at'])) {
            if (isset($params['first_at'][0]) && $params['first_at'][0]) {
                $model = $model->having('first_at', '>=', $params['first_at'][0]);
            }
            if (isset($params['first_at'][1]) && $params['first_at'][1]) {
                $model = $model->having('first_at', '<=', $params['first_at'][1]);
            }
        }
        if (isset($params['new_at']) && $params['new_at'] && is_array($params['new_at'])) {
            if (isset($params['new_at'][0]) && $params['new_at'][0]) {
                $model = $model->having('new_at', '>=', $params['new_at'][0]);
            }
            if (isset($params['new_at'][1]) && $params['new_at'][1]) {
                $model = $model->having('new_at', '<=', $params['new_at'][1]);
            }
        }
        if (isset($params['order']) && in_array($params['order'], ['max_price', 'min_price'])) {
            $by = isset($params['by']) && $params['by'] ? $params['by'] : 'desc';
            $model = $model->orderBy($params['order'], $by);
        }
        return $model->paginate(isset($params['per_page']) ? $params['per_page'] : 15);
    }
}
